//
// Created by dave on 18-7-29.
//

#pragma once

#include <string>
#include <vector>
#include "../msg_body.h"
#include "../data_utils.h"
#include <boost/date_time.hpp>

class LocationReport : public MsgBody {
public:
    void decode(std::vector<char> data, std::size_t start, std::size_t stop) override {
        alarm_ = read_dword(data, start);
        flag_ = read_dword(data, start + 4);
        located_ = (flag_ & 2) > 0;
        lat_ = read_dword(data, start + 8) / 1000000.0;
        lng_ = read_dword(data, start + 12) / 1000000.0;
        height_ = read_word(data, start + 16);
        speed_ = read_word(data, start + 18);
        direction_ = read_word(data, start + 20);
        time_ = parse_time(read_bcd(data, start + 22, 6));
    }

    std::vector<char> encode() override {
        std::vector<char> vec;
        write_dword(vec, alarm_);
        write_dword(vec, flag_);
        write_dword(vec, static_cast<unsigned int>(lat_ * 1000000));
        write_dword(vec, static_cast<unsigned int>(lng_ * 1000000));
        write_word(vec, static_cast<unsigned short>(height_));
        write_word(vec, static_cast<unsigned short>(speed_));
        write_word(vec, static_cast<unsigned short>(direction_));
        write_bcd(vec, format_time(time_));
        return vec;
    }

    unsigned getAlarm() const { return alarm_; }
    void setAlarm(unsigned alarm) { this->alarm_ = alarm; }

    unsigned getFlag() const { return flag_; }
    void setFlag(unsigned flag) { this->flag_ = flag; }

    bool isLocated() const { return located_; }
    void setLocated(bool located) { LocationReport::located_ = located; }

    double getLat() const { return lat_; }
    void setLat(double lat) { this->lat_ = lat; }

    double getLng() const { return lng_; }
    void setLng(double lng) { this->lng_ = lng; }

    int getHeight() const { return height_; }
    void setHeight(int height) { this->height_ = height; }

    int getSpeed() const { return speed_; }
    void setSpeed(int speed) { this->speed_ = speed; }

    int getDirection() const { return direction_; }
    void setDirection(int direction) { this->direction_ = direction; }

    time_t getTime() const { return time_; }
    void setTime(time_t time) { this->time_ = time; }

private:
    unsigned alarm_;
    unsigned flag_;
    bool located_;
    double lat_;
    double lng_;
    int height_;
    int speed_;
    int direction_;
    time_t time_;
};